home *** CD-ROM | disk | FTP | other *** search
- {
- A couple of months ago, I posted an unfinished procedure to move a row of
- pixels one pixel to the left and asked for help. Didn't get any response
- (pretty normal, since it's really a lot of work to figure out someone else's
- assembler code :), but in the meantime I've been able to finish it. Don't know
- whether there's still anybody out there who can use it (the original
- requester, Fabian Thylman(n?), seems to have left Fidonet), but here it is
- anyway...
- }
-
- PROCEDURE MoveRow1PixelLeft(x,y, length: WORD; VAR tempbuf);
- {For Mode-X, 320*200*4. Moves length pixels at (x,y) one position to the
- left.}{Tempbuf should be an array of byte/char, with size = length div 4.
- }{Public domain by Jonas Maebe (2:292/624.7). SWAG, you can include this if
- }{you guys feel like it :)
- }ASSEMBLER;
- VAR sisav, disav: word;
- planecount: byte;
- ASM
- cld
- push ds
- mov ax, $a000
- mov di, x
- mov ds, ax {ds = videosegment}
- mov bx, di {bx = di = x}
- mov ax, y
- shr di, 2
- shl ax, 5
- add di, ax
- shl ax, 2
- add di, ax {di = y * 160 + x div 4}
- mov si, di {source = destination = (x,y)}
- and bl, 11b
- mov bh, bl {bh holds value for read plane}
- dec bl {write plane points to previous plane}
- cmp bl, $ff {bl = -1?}
- jne @bl_ok
- mov bl, 3 {set bl so it points to plane four (write plane)}
- dec di {and di to point to the previous memlocation}
- @bl_ok:
- mov cl, bl
- mov bl, 1
- shl bl, cl {bl holds value to set the write plane}
- mov cx, length {cx holds the length of the row that has to be}
- {moved}
- mov sisav, si
- mov disav, di {save si and di for later}
- mov planecount, 3 {and initialize the plane counter}
- mov dx, grac
- mov ah, bl {set read plane to value of writeplane, first save}
- dec ah {all pixels that'll be overwritten by the first move}
- jns @ok
- xor ah, ah {the next few adjustments are still a mystery to me}
- @ok: {and I've have found them out by trial and error.}
- cmp ah, 3 {If anyone can explain *WHY* the read plane has to}
- jne @ok2 {set this way, please do tell me...}
- dec ah
- @ok2:
- mov al, 4
- out dx, ax
- mov si, di
- sub cx, 3
- inc si
- les di, tempbuf
- shr cx, 3
- jnc @even
- movsb
- @even: {all pixels that are to be overwritten are saved in}
- rep movsw {tempbuf}
- mov si, sisav
- mov di, disav
- mov ax, $a000
- mov cx, length
- mov es, ax
- @newplane:
- mov dx, grac
- mov ah, bh
- mov al, 4
- out dx, ax {select read plane}
- @writeplane:
- mov dx, sequ
- mov ah, bl
- mov al, 2
- out dx, ax {select write plane}
- shr cx, 3 {shr 2 because there are 4 planes + shr 1 because}
- jnc @counter_even {we're doing movsw's, only the last shifted-out}
- movsb {bit is kept in the carry flag}
- @counter_even:
- rep movsw {move pixels}
- cmp planecount, 0
- je @end
- mov cx, length {reload the counter}
- mov si, sisav {restore si}
- dec cx {decrease the length by one; because we move on to}
- {the next pixel, the length of the row becomes one}
- {less}
- mov di, disav {restore di}
- mov length, cx {and save the length}
- inc bh {increase the read plane}
- cmp bh, 4 {if it's four, wrap around since there are only 4}
- {planes to read from (and with 4 it would point to 5)}
- jne @noreset_bh
- mov bh, 0 {reset bh}
- inc si {next pixel because we reset bh}
- mov sisav, si {plane zero}
- @noreset_bh:
- cmp bl, 1000b {test if it points to the 4th plane}
- je @reset_bl
- add bl, bl {increase write plane (same as shl bl, 1)}
- dec planecount
- jnz @newplane {planecounter 0 -> finish him! :)}
- lds si, tempbuf
- jmp @writeplane {it doesn't -> don't reset}
- @reset_bl:
- mov bl, 1 {select plane 0}
- inc di {and point to the next pixel, same reason as with}
- mov disav, di {read plane}
- dec planecount
- jnz @newplane {planecounter 0 -> finish him! :)}
- lds si, tempbuf
- jmp @writeplane
- @end:
- mov ah, 1
- mov cl, bh
- shl ah, cl
- mov al, 2 {let the write plane point to the last pixel}
- out dx, ax {we've read (write plane = read plane)}
- mov si, sisav
- mov cx, length
- shr cx, 2
- jnc @even2
- inc si
- @even2:
- add si, cx
- xor bl, bl
- mov es:[si], bl {and zero the last pixel (erase it)}
- pop ds {restore data segment}
- END;